package {
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Loader;
	import flash.display.Shape;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.net.Socket;
	import flash.net.URLRequest;

[SWF(width="640",height="400",backgroundColor="0x0000ff",frameRate="60")]
	public class PanzerFlash extends Sprite
	{
	public static function allowDomain(domain1:String):void{}
		//
		private var msg:MsgText = null;
		private var b:Boolean = false;
		//
		private var m_pBodyTex:BitmapData = null;
		private var m_pGunTex:BitmapData = null;
		private var m_pTank:Sprite = null;
		private var m_iMx:Number = 0;//拖放操作起点
		private var m_iMy:Number = 0;
		private var m_iDragStyle:int = 0x00; //0x00-车身起, 0x10-地面起
		private var m_bMovePointer:Boolean = false;//移动指令
		private var m_bFrontWard:Boolean = true;//向前
		private var m_iDirect:int = 0;//向左 -1 向右 +1
		private var m_iRotation:Number = 0;//目标朝向
		private var m_iPx:Number = 0;//目标坐标
		private var m_iPy:Number = 0;
		private var m_iSpeed:Number = 2;//实际车速,限定最大车速1
		private var m_iRad:Number = 0.4;//实际角速度,限定最大角速度1
		private var m_bShotPointer:Boolean = false;//射击指令
		private var m_bQuickShot:Boolean = true;//立即射击 - 符合目标射向即射击 - 拖放在最小射程内设为false,否则为true
		private var m_iGunRotation:Number = 0;//目标射向 - 真方位

		public function PanzerFlash()
		{
			msg=new MsgText(this);
			InitTank();
			//var t:MomoTank = new MomoTank(0,100,100,0,0);
			var map:BFmap = new BFmap;
			map.LoadXML(new XML);
			map.InitMap();
			this.addEventListener(Event.ENTER_FRAME,UpdataCheck);
			stage.addEventListener(MouseEvent.MOUSE_DOWN,MouseDown);
			stage.addEventListener(MouseEvent.MOUSE_UP,MouseUp);
		}
		//
		private function UpdataCheck( e:Event ):void{
			if(m_pBodyTex==null)return;
			if(m_pBodyTex){
				if(m_pTank){
					Updata();
					return;
				}
				else{
					m_pTank = new Sprite;
					m_pTank.x=100;
					m_pTank.y=100;
					var body:Shape = new Shape;
					body.x=-m_pBodyTex.width*0.65;
					body.y=-m_pBodyTex.height*0.5;
					body.graphics.lineStyle(1,0,0);
					body.graphics.beginBitmapFill(m_pBodyTex,null,true,true);
					body.graphics.drawRect(0,0,m_pBodyTex.width-1,m_pBodyTex.height-1);
					body.graphics.endFill();
					m_pTank.addChild(body);
					this.addChild(m_pTank);
					var gun:Shape = new Shape;
					var gunSp:Sprite = new Sprite;
					gun.x=-m_pGunTex.width*0.3;	//炮塔旋转轴心相当于炮塔的位置
					gun.y=-m_pGunTex.height*0.5;
					gunSp.x=-4;	//炮塔轴心相当于车体的位置
					gunSp.y=0;
					gun.graphics.lineStyle(1,0,0);
					gun.graphics.beginBitmapFill(m_pGunTex,null,true,true);
					gun.graphics.drawRect(0,0,m_pGunTex.width-1,m_pGunTex.height-1);
					gun.graphics.endFill();
					gunSp.addChild(gun);
					m_pTank.addChild(gunSp);
					
				}
			}
		}
		private function Updata():void{
			//设定炮塔转向
			var mx:Number=stage.mouseX;
			var my:Number=stage.mouseY;
			var tx:Number=m_pTank.x-4;
			var ty:Number=m_pTank.y+0;
			m_pTank.getChildAt(1).rotation=atg(my-ty,mx-tx)-m_pTank.rotation;//注意这个getChildAt(1)
			PointerMove();
			msg.text = "MovePointer "+m_bMovePointer.toString();
			msg.text+= "\n"+"TankRotation "+int(m_pTank.rotation).toString();
			msg.text+= "\n"+"MoveRotation "+int(m_iRotation).toString();
			if(m_bFrontWard)
				msg.text+= "\n"+"进车";
			else
				msg.text+= "\n"+"倒车";
			msg.text+= "\n"+"相差angle "+int(atg(m_iPy-m_pTank.y,m_iPx-m_pTank.x+4)-m_pTank.rotation).toString();
		}
		//
		public function PointerMove():void{	//指令移动
			var tx:Number=m_pTank.x-4;
			var ty:Number=m_pTank.y+0;
			var na:Number=0;

			if(!m_bMovePointer){
				if(m_iRotation!=1000){
					//转到目标朝向
					na=m_iRotation-m_pTank.rotation;
					while(na>180)na-=360;
					while(na<-180)na+=360;//调整到-180~180
					if( na>1 )m_pTank.rotation+=m_iRad;//调整目标朝向
					if( na<-1)m_pTank.rotation-=m_iRad;
				}
				return;//无指令,返回
			}
			//是否需要调整角度 - 应该是,需要左转就左转,需要右转就右转,不需要就算了
			var aa:Number = atg(m_iMy-ty,m_iMx-tx);//貌似此处无意义
			
			if(m_bFrontWard){//进车
				na = aa-m_pTank.rotation;//求角度
				while(na>180)na-=360;
				while(na<-180)na+=360;//调整到-180~180
				if(na>2){//角度没到位
					m_pTank.rotation+=m_iRad;
				}
				else if(na<-2){
					m_pTank.rotation-=m_iRad;
				}
				else{
					m_pTank.rotation=aa;//应该吗?
				} 
			}
			else{//倒车
				na = aa-m_pTank.rotation-180;//求角度
				while(na>180)na-=360;
				while(na<-180)na+=360;//调整到-180~180
				if(na>2){//角度没到位
					m_pTank.rotation+=m_iRad;
				}
				else if(na<-2){
					m_pTank.rotation-=m_iRad;
				}
				else{
					var ta:Number=aa-180;
					while(ta<0)ta+=360;
					m_pTank.rotation=ta;//应该吗?
				} 
			}
			//求平均速度
			var l2:Number=len2(m_iMx-tx,m_iMy-ty);
			//l2/(Math.abs(na)/1);// 转动需要时间为转动角度除以最大转动角速度,距离除以时间等于速度
			m_iSpeed=l2/(Math.abs(na)/m_iRad);
			if(m_iSpeed>1)m_iSpeed=1;//不能超过最大速度
			if(l2>4){
				if(m_bFrontWard){
					m_pTank.x+=m_iSpeed*cos(m_pTank.rotation);
					m_pTank.y+=m_iSpeed*sin(m_pTank.rotation);
				}
				else{
					m_pTank.x+=m_iSpeed*cos(m_pTank.rotation-180);
					m_pTank.y+=m_iSpeed*sin(m_pTank.rotation-180);
				}
			}
			else{
				m_bMovePointer=false;
			}
		}
		//
		public function PointerShot():void{
			var aa:Number = m_pTank.getChildAt(1).rotation-m_pTank.rotation;
			var na:Number = aa-m_iGunRotation;
			while(na>180)na-=360;
			while(na<-180)na+=360;
			if(Math.abs(na)<1)m_pTank.getChildAt(1).rotation=m_pTank.rotation+m_iGunRotation;
			if(na>0)m_pTank.getChildAt(1).rotation++;
			if(na<0)m_pTank.getChildAt(1).rotation--;
		}
		//
		public function MouseDown( e:MouseEvent ):void{
			m_iMx=stage.mouseX;
			m_iMy=stage.mouseY;
			if( m_pTank.hitTestPoint(m_iMx,m_iMy) ){//在车身范围内 - 调整炮塔 - 如果有的话
				m_iDragStyle = 0x00;
				//显示瞄准图
			}
			else{
				m_iDragStyle = 0x10;
				//显示移动目的地
			}
		}
		public function MouseUp( e:MouseEvent ):void{
			//注意:只有鼠标左键释放
			m_iPx=stage.mouseX;
			m_iPy=stage.mouseY;
			var t_bDragMode:Boolean = true;
			var t_iDragLength:Number = len2(m_iMx-m_iPx,m_iMy-m_iPy);
			//根据拖放距离判断
			if( t_iDragLength<50 )t_bDragMode=false;//拖放距离太小,不算拖放
			if(m_iDragStyle==0x00){
				m_bShotPointer=true;
				m_iGunRotation = atg(m_iPy-m_iMy,m_iPx-m_iMx);//设定新射向 - 不应该是Mx和My的位置,提供坐标图供观察用
				if(t_iDragLength<200)	//根据拖放距离判断是否射击
					m_bQuickShot=false;
				else
					m_bQuickShot=true;
				
			}
			else if(m_iDragStyle==0x10){
				m_bMovePointer=true;
				var tx:Number = m_pTank.x;
				var ty:Number = m_pTank.y;
				var aa:Number = atg(m_iMy-ty,m_iMx-tx);
				var na:Number = aa-m_pTank.rotation;//求角度
				while(na>180)na-=360;
				while(na<-180)na+=360;//调整到-180~180
				//根据角度判断是进车还是倒车,是左转还是右转
				if(na<135 && na>-135)
					m_bFrontWard=true;
				else
					m_bFrontWard=false;
				if(m_bFrontWard){
					if(na<0)
						m_iDirect=-1;
					else
						m_iDirect=1;
				}
				else{
					if(na<0)
						m_iDirect=1;
					else
						m_iDirect=-1;
				}
				//设定目标朝向
				if(t_iDragLength>100)
					m_iRotation=atg(m_iPy-m_iMy,m_iPx-m_iMx);
				else
					m_iRotation=1000;//即无设定朝向 - 到位不转向
			}
			
		}
		//
		private function InitTank():void{
			var bmp:Bitmap = null;
			var loader:Loader = new Loader;
			var loader2:Loader = new Loader;
			loader.contentLoaderInfo.addEventListener(Event.COMPLETE,loadCompleted);
			loader.load( new URLRequest("T34.png") );
			loader2.contentLoaderInfo.addEventListener(Event.COMPLETE,loadCompleted2);
			loader2.load( new URLRequest("T34-76.png") );
		}
		//
		private function loadCompleted( e:Event ):void{
			var bmp:Bitmap = e.target.content as Bitmap;
			m_pBodyTex=bmp.bitmapData;
		}
		private function loadCompleted2( e:Event ):void{
			var bmp:Bitmap = e.target.content as Bitmap;
			m_pGunTex=bmp.bitmapData;
		}
		
		static public const s_PI_180:Number = 180/Math.PI;
		static public const s_180_PI:Number = Math.PI/180;
		static public function sin( v:Number ):Number{
			return Math.sin(v*s_180_PI);
		}
		static public function cos( v:Number ):Number{
			return Math.cos(v*s_180_PI);
		}
		static public function atg( y:Number, x:Number ):Number{	//求反正切,返回0-359度
			if(x==0){
				if(y==0)return 0;	//两点重合
				if(y>0)return -90;	//0度角,在flash坐标系中为-90度
				return 90;//-90度角,在flash坐标系中为90度
			}
			var a:Number = Math.atan(y/x)*s_PI_180;
			if(x>0)return a;
			return a+180;
		}
		static public function len2( x:Number, y:Number ):Number{
			return Math.sqrt(x*x+y*y);
		}
	}
}
/* ps - |
 初始载入界面->菜单->进入地图界面->地图一览中->结束判定界面
 需要的资源: 建筑\林木\桥梁\水流\地形\步兵\粒子
 */
/*
			//s.connect("localhost",1100);
			socket.addEventListener(Event.CONNECT, connectHandler);
			socket.addEventListener(Event.CLOSE, closeHandler);
			socket.addEventListener(ErrorEvent.ERROR, errorHandler);
			socket.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
			socket.addEventListener(ProgressEvent.SOCKET_DATA, dataHandler);
 * 
 这样就完成socket的初始化了，接下来是等待连接成功或者失败的消息。消息的处理函数是自己定义的，如果连接成功了，就可以在自己的函数里发消息给服务端。也是很简单。
// 定义一个要传递消息的ByteArray
var t_byteArr:ByteArray;
// 然后写一个数字1进去
t_byteArr.writeByte(1);

//把这个消息写到socket里面去
socket.writeBytes(t_byteArr);

// 执行flush，socket就把消息发出去了
socket.flush();

至于服务端部分，和普通的tcp/ip通讯的应用程序是一样，随便找一个写就行了。
*/